#!/usr/bin/env python
import random,sys, math
import numpy as np
from pympler.classtracker import ClassTracker
from pympler.classtracker_stats import Stats
from operator import itemgetter
import spacesaving as SS
from util import Timer
from time import gmtime, strftime
import pickle
import cProfile as profile
import pstats
import os

def round_slice_and_sort(_list,max):
	lim = min(max,len(_list))
	return sorted(map(lambda x: (x[0], round(x[1],3)), _list),key=itemgetter(1),reverse=True)[:lim]


def count_exact(a,limit):
	count = {}
	for item in a :
		if item[0] not in count :
			count[item[0]] = 0.0
		count[item[0]] += (item[1])

	exact = []
	for k,v in count.iteritems() :
		exact.append((k,round(v,3)))

	exact=sorted(exact,key=itemgetter(1),reverse=True)
	return exact[:limit]


def traceB(a, eps,k,limit) :
	ssbb = SS.SpaceSavingBucketBuffer(eps, k)
	for item in a :
		ssbb.add(item)
	return

def traceC(a, eps,k,limit) :
	sshb = SS.SpaceSavingHashBuffer(eps, k)
	for item in a :
		sshb.add(item)
	return

def traceA(a, eps,k,limit) :

	ssb = SS.SpaceSavingBucket(eps)
	for item in a :
		ssb.add(item)
	return
#	pickle.dump(results, foutput)
#	foutput.close()
#	tracker.stats.dump_stats(prof, False)

def combineanddump(files):
	stat = pstats.Stats(files[0])
	stat.add(files[1])
	stat.add(files[2])
	stat.strip_dirs()
	stat.dump_stats(files[0][:-2])
	for file in files :
		os.remove(file)

def main() :

	files = ['input_zipf_1000000_2.0']
	out_dir = "../out/"
	data_dir = "../../data/"

	for filename in files :
		limit = 100
		skew = filename.split('_')[3]
		inputsize = filename.split('_')[2]

		ts = strftime("%d%m%y-%H.%M.%S", gmtime())
		_input = open(data_dir +  filename)
		a = pickle.load(_input)

#		RESULTS = []
#		global tracker
#		tracker = ClassTracker()
#		tracker.track_class(SS.SpaceSavingBucket, resolution_level=2)
#		tracker.track_class(SS.SpaceSavingBucketBuffer, resolution_level=2)
#		tracker.track_class(SS.SpaceSavingHashBuffer, resolution_level=2)
		print "k\tSSB\tSSBB\tSSHB"

		for j in range(3) :
			x = int(math.pow(10, j))
			for i in range (1,14) :
				if j == 0 and i == 1 : continue
				if j < 2 and i > 10 : break
				k = int(i * x)
				eps = float(1.0/k)
#				results = {}
#				results["info"] = {"input":inputsize, "eps": eps, "k": k, "skew": skew}
#				results["ssb"] = {}
#				results["ssbb"] ={}
#				results["sshb"] = {}
				files = []
				for i in range(3) :
					_filename = out_dir + "_".join(["ssbs", str(inputsize), str(skew), str(k), str(i)])
					files.append(_filename)
					profile.runctx('traceA(a, eps, k, limit)', globals(), {'a': a, "eps" : eps, "k": k, 'limit': limit}, filename=_filename)
				combineanddump(files)
				files = []

				for i in range(3) :
					_filename = out_dir + "_".join(["ssbb", str(inputsize), str(skew), str(k),str(i)])
					files.append(_filename)
					profile.runctx('traceB(a, eps, k, limit)', globals(), {'a': a, "eps" : eps, "k": k, 'limit': limit},filename=_filename)

				combineanddump(files)
				files = []
				for i in range(3) :
					_filename = out_dir + "_".join(["sshb", str(inputsize), str(skew), str(k),str(i)])
					files.append(_filename)
					profile.runctx('traceC(a, eps, k, limit)', globals(), {'a': a, "eps" : eps, "k": k, 'limit': limit},filename=_filename)
				combineanddump(files)

#		fprofile = out_dir + "_".join([ts,str(inputsize), str(skew), "2-9000","profile"])
#		prof = open(fprofile ,'w')
#		tracker.stats.dump_stats(prof, False)

#		foutput = out_dir + "_".join([ts,str(inputsize), str(skew), "2-9000","output"])
#		foutput = open(foutput,'w')
#		pickle.dump(RESULTS, foutput)
#		foutput.close()
#def trace(a, results, eps,k,limit) :

main()